<template>
  <div :class="`win-container ${componentStyle}-Style`">
    <div
      v-if="isDesignViewNew"
      class="vis-com-win-container-isDesignView"
    >
      <el-icon v-if="!showWinContainer" class="Menu" @click="showWinContainer=true"><MenuIcon /></el-icon>
      <win-index
        v-if="showWinContainer"
        :config="config"
        :win-style="getWinLocationStyle"
        :is-design-view="isDesignViewNew"
        :widget-id="widgetId"
        :widget-instance-id="widgetInstanceId"
        :widget-name="widgetName"
        :layout="layout"
        :title="title"
        :isTitleFixed="isTitleFixed"
        :variableTitle="variableTitle"
        :w="w"
        :h="h"
        :parent-id="widgetInstanceId"
        @close-win="closeWin"
      >
      </win-index>
    </div>
    <el-dialog
      v-if="!isDesignViewNew && showWinContainer"
      title=""
      :modal-class="{'disabled-mask':!mask}"
      :model-value="true"
      width="0%"
      :modal="false"
      :close-on-click-modal="false"
      :show-close="false"
      :close-on-press-escape="false"
      :style="dialogStyle"
      :modal-append-to-body="true"
      :append-to-body="true"
      :class="{'animation': dlgAnimation,  [`${xvueNameSpace}`]: true}"
    >
      <span>
        <win-index
          :config="config"
          :win-style="getWinLocationStyle"
          :is-design-view="isDesignViewNew"
          :widget-id="widgetId"
          :widget-instance-id="widgetInstanceId"
          :widget-name="widgetName"
          :layout="layout"
          :title="title"
          :isTitleFixed="isTitleFixed"
          :variableTitle="variableTitle"
          :w="w_"
          :h="h_"
          :parent-id="widgetInstanceId"
          :dlgAnimation="dlgAnimation"
          @close-win="closeWin"
        >
        </win-index>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import chartBase from '@/mixin/chart-base.js';
import { EMIT_PARAMS_OBJ } from '@/utils/constant';
import { convertValue } from '@/utils/util.js';
import { Menu as MenuIcon } from '@element-plus/icons-vue';
import { nextTick } from 'vue';
import { mapState } from 'vuex';
import config from './config/config.js';
import dfCssStyle from './config/cssStyle-default.js';
import winIndex from './win/winIndex.vue';

export default {
  name: 'VisWinContainer',
  components: {
    winIndex,
    MenuIcon,
  },
  mixins: [chartBase],
  provide() {
    return {
      provideObj: this.provideObj,
    };
  },
  props: ['isDesignView', 'parentId', 'widgetId', 'widgetInstanceId', 'widgetName', 'w', 'h', 'layout', 'x', 'y'],
  data() {
    const _config = JSON.parse(JSON.stringify(config));
    return {
      xvueNameSpace: process.env.xvueNameSpace, // 给挂载在body下的元素加上主类名
      ..._config.config.property,
      showWinContainer: false,
      dfCssStyle,
      isWinContainer: true, // 用于子组件查询弹窗组件标记
      provideObj: {
        provideCameraIndexCodes: '',
      },
    };
  },
  computed: {
    ...mapState({
      winContainers: state => state.VisualComponentsModule.winContainers,
    }),
    isDesignViewNew() {
      if (this.isDesignView === true || this.isDesignView === false) {
        return this.isDesignView;
      }
      return true;
    },
    getWinLocationStyle() {
      const obj = {};
      if (this.isDesignViewNew) {
        return obj;
      }
      obj.width = `${this.w_}px`;
      obj.height = `${this.h_}px`;
      if (this.config?.config?.property?.isHideTopABar) {
        obj.height = `${this.h_ - convertValue(40, 0, 'h')}px`;
      }
      obj.position = 'absolute';
      if (this.isDesignViewWinLocation) {
        obj.left = `${convertValue(this.x, 0, 'w')}px`;
        obj.top = `${convertValue(this.y, 0, 'h')}px`;
        return obj;
      }
      switch (this.winLocation) {
        case 'winCenter':
          obj.left = `calc( 50% - ${this.w_ / 2}px)`;
          obj.top = `calc( 50% - ${this.h_ / 2}px)`;
          break;
        case 'winLeftTop':
          obj.left = '0px';
          obj.top = '0px';
          break;
        case 'winLeftDown':
          obj.left = '0px';
          obj.bottom = '0px';
          break;
        case 'winRightTop':
          obj.right = '0px';
          obj.top = '0px';
          break;
        case 'winRightDown':
          obj.right = '0px';
          obj.bottom = '0px';
          break;
        default:
          obj.left = `calc( 50% - ${this.w_ / 2}px)`;
          obj.top = `calc( 50% - ${this.h_ / 2}px)`;
          break;
      }
      return obj;
    },
    dialogStyle() {
      return {
        width: 0,
      };
    },
    w_() {
      return convertValue(this.w, 0, 'w');
    },
    h_() {
      // 高度方向不做自适应，不然内容超出容器
      return this.h;
    },
  },
  watch: {
    showWinContainer(visible) {
      if (visible) {
        // 触发内部组件重新渲染
        this.setState({ curWinContainerWid: '' });
        nextTick(() => {
          this.setState({
            curWinContainerWid: this.widgetInstanceId,
          });
        });

        // 如果隐藏了顶部栏，则通过点击弹窗外部区域进行关闭
        if (this.isHideTopABar) {
          setTimeout(() => {
            window.addEventListener('click', this.closeWinContainer);
          }, 20);
        }
      }
      this.designToggleMode();
    },
  },
  created() {
    this.orgConfig = JSON.parse(JSON.stringify(config));
    this.config = JSON.parse(JSON.stringify(config));
    this.addToState();
  },
  mounted() {
    this.designToggleMode();
    this.initPreviewZIndex();
  },
  beforeUnmount() {
    this.delFromState();
  },
  methods: {

    // 编辑态切换显示模式，节省空间，内存
    designToggleMode() {
      const gridEl = this.$el.parentElement;
      if (this.isDesignViewNew) {
        if (this.showWinContainer) {
          gridEl.removeAttribute('vis-wincontainer-grid');
        } else {
          gridEl.setAttribute('vis-wincontainer-grid', 1);
        }
      }
    },

    // 预览态防止遮挡别的组件
    initPreviewZIndex() {
      if (!this.isDesignViewNew) {
        this.$el.parentElement.setAttribute('vis-wincontainer-grid-preview', 1);
      }
    },
    loadWidget(pageStatus) {
      this.updateConfigProperty();
      this.afterLoadWidget();
    },
    closeWin() {
      this.showWinContainer = false;
      this.executeAction();
    },
    closeWinContainer(event) {
      if (event.target.classList.contains(`win-index-wrapper-${this.widgetInstanceId}`)) {
        this.closeWin();
        window.removeEventListener('click', this.closeWinContainer);
      }
    },

    // 高级事件联动触发弹窗
    runAdvLinkage(evts) {
      if (this.eventControlStatus) {
        if (evts.length) {
          const obj = evts[evts.length - 1];
          const paramsObj = this.config.events.find(e => e.type === 'in' && e.key === obj.evtKey);
          let getParamKey = 'isOpenWin';
          paramsObj?.dbFields?.forEach(({ dbField, paramKey })=>{
            if (dbField === 'isOpenWin' && paramKey) {
              getParamKey = paramKey;
            }
          });
          const acceptObj = obj?.params?.find(item=>item.evtParameterKey === getParamKey) || {};
          const acceptValue = acceptObj.evtParameterVal;
          this.dealWinStatus(acceptValue);
        }
      } else {
        if (evts.length) {
          this.showWinContainer = true;
        }
      }
    },
    acceptEvtMsg(paramters, key, obj) {
      let flag = false;
      let variableTitle;
      let params = {};
      for (const _key in obj) {
        if (_key.indexOf(EMIT_PARAMS_OBJ) > -1) {
          const o = obj[_key];
          if (o.eventKey) {
            const event = this.config.events.find(e => e.type === 'in' && e.key === o.eventKey);
            if (event) {
              flag = true;
              params = event;
              this.provideObj.provideCameraIndexCodes = obj[_key].parameters.thing_id;
            }
            if (this.selectAcceptEvt === event.key) {
              variableTitle = obj[_key].parameters[this.evtAttribute];
            }
            break;
          }
        }
      }
      if (flag) {
        this.acceptEvtMsgCallback(obj, params);
        if (!this.isTitleFixed) {
          this.variableTitle = variableTitle || this.variableTitle;
        }
      }
    },
    acceptEvtMsgCallback(obj, paramsObj) {
      if (this.eventControlStatus) {
        if (obj) {
          let acceptObj = {};
          Object.entries(obj || {}).forEach(([key, value])=>{
            if (key.indexOf(EMIT_PARAMS_OBJ) > -1) {
              acceptObj = value;
            }
          });
          let getParamKey = 'isOpenWin';
          paramsObj?.dbFields?.forEach(({ dbField, paramKey })=>{
            if (dbField === 'isOpenWin' && paramKey) {
              getParamKey = paramKey;
            }
          });
          const paramKey = paramsObj?.dbFields?.length ? getParamKey : 'isOpenWin';
          const acceptValue = acceptObj?.parameters?.[paramKey];
          this.dealWinStatus(acceptValue);
        }
      } else {
        this.showWinContainer = true;
      }
    },
    dealWinStatus(acceptValue) {
      if (!acceptValue && acceptValue !== 0) {
        return;
      }
      const openWinParamsList = this.openStatusParams?.split(';')?.filter(id=>id);
      const closeWinParamsList = this.closeStatusParams?.split(';')?.filter(id=>id);
      if (
            openWinParamsList.includes(acceptValue) ||
            (!openWinParamsList.length && closeWinParamsList.length && !closeWinParamsList.includes(acceptValue)) ||
            (!openWinParamsList.length && !closeWinParamsList.length)
      ) {
        this.showWinContainer = true;
      }
      closeWinParamsList.includes(acceptValue) && (this.showWinContainer = false);
    },
    addToState() {
      const arr = [...this.winContainers];
      arr.push(this.widgetInstanceId);
      this.setState({
        winContainers: arr,
      });
    },
    delFromState() {
      const arr = [...this.winContainers];
      for (let i = 0; i < arr.length; i++) {
        if (arr[i] === this.widgetInstanceId) {
          arr.splice(i, 1);
        }
      }
      this.setState({
        winContainers: arr,
      });
    },
  },
};
</script>

<style lang="less" scoped>
.win-container {
  width: 100%;
  height: 100%;
  position: relative;
  .vis-com-win-container-isDesignView {
    width: 100%;
    height: 100%;
    position: relative;
    .Menu{
      position: absolute;
      left: 50%;
      top: 50%;
      font-size: 40px;
      cursor: pointer;
      transform: translate(-50%, -50%);
      color: #98cae6;
    }
  }
}
</style>
<style lang="less">
[vis-wincontainer-grid]{
  width: 50px !important;
  height: 50px !important;
}
[vis-wincontainer-grid-preview]{
  z-index: 0 !important;
}
</style>
